﻿using System;
using System.Runtime.Serialization;
using System.Web.UI.WebControls;
using System.Linq.Expressions;
using System.Collections.Specialized;
using Mvc.XForms.Utilities;

namespace Mvc.XForms.UI {
	[DataContract]
	public abstract class PagedSortedList<T> : GridItems<T>, IPagedSortedList<T> {
		// Empty constructor so inherited objects can determine init order
		protected PagedSortedList() { }

		protected PagedSortedList(NameValueCollection collection, string pageIndexKey, string sortExpressionKey, string sortDirectionKey, int pageSize, Expression<Func<T, object>> defaultSort, SortDirection defaultSortDirection)
			: this(collection, pageIndexKey, sortExpressionKey, sortDirectionKey, pageSize, defaultSort.Body.ExtractID(), defaultSortDirection) { }

		protected PagedSortedList(NameValueCollection collection, string pageIndexKey, string sortExpressionKey, string sortDirectionKey, int pageSize, string defaultSortExpression, SortDirection defaultSortDirection)
			: this(new PagedSortedParameters(collection, pageIndexKey, sortExpressionKey, sortDirectionKey, pageSize, defaultSortExpression, defaultSortDirection)) { }

		protected PagedSortedList(IPagedSortedParameters gridParams) {
			InitWithParams(gridParams);
		}

		protected PagedSortedList(int pageIndex, int pageSize, string sortExpression, SortDirection sortDirection) {
			Init(pageIndex, pageSize, sortExpression, sortDirection);
		}

		protected void InitWithParams(IPagedSortedParameters gridParams) {
			SetParameters(gridParams);
			Init(gridParams.PageIndex, gridParams.PageSize, gridParams.SortExpression, gridParams.SortDirection);
		}

		protected void Init(int pageIndex, int pageSize, string sortExpression, SortDirection sortDirection) {
			PageIndex = pageIndex;
			PageSize = pageSize;
			SortExpression = sortExpression;
			SortDirection = sortDirection;
			TotalCount = GetTotalCount();
			PageCount = this.GetPageCount();

			// Sanitise page index
			PageIndex = this.GetValidPageIndex(pageIndex);

			ApplySorting();
			ApplyPaging();
		}

		public void SetParameters(IPagedSortedParameters gridParams) {
			// Paging
			PageIndex = gridParams.PageIndex;
			PageSize = gridParams.PageSize;
			PageIndexKey = gridParams.PageIndexKey;

			// Sorting
			SortExpression = gridParams.SortExpression;
			SortDirection = gridParams.SortDirection;
			SortExpressionKey = gridParams.SortExpressionKey;
			SortDirectionKey = gridParams.SortDirectionKey;
		}

		protected abstract int GetTotalCount();
		protected abstract void ApplySorting();
		protected abstract void ApplyPaging();

		[DataMember]
		public int PageIndex { get; protected set; }
		[DataMember]
		public int PageSize { get; protected set; }
		[DataMember]
		public int PageCount { get; protected set; }
		[DataMember]
		public int TotalCount { get; protected set; }
		[DataMember]
		public string PageIndexKey { get; protected set; }
		[DataMember]
		public string SortExpression { get; set; }
		[DataMember]
		public SortDirection SortDirection { get; set; }
		[DataMember]
		public string SortExpressionKey { get; protected set; }
		[DataMember]
		public string SortDirectionKey { get; protected set; }

		public bool IsPrevious {
			get { return this.GetIsPrevious(); }
		}
		public bool IsNext {
			get { return this.GetIsNext(); }
		}
	}
}